import cv2
import numpy as np


def detect_and_save_circles(image_path, output_path):
    """
    检测图像中的圆形并计算其直径，在图上绘制圆形和标注直径，保存结果图像。

    参数:
        image_path (str): 输入图像的路径。
        output_path (str): 输出图像的保存路径。

    返回:
        list: 包含检测到的圆形信息的列表，每个元素是一个字典，
              格式为 {'center': (x, y), 'radius': r, 'diameter': diameter}。
    """
    # 读取图像
    image = cv2.imread(image_path)
    scale_factor = 0.1  # 缩小倍数，可以根据需要调整
    image = cv2.resize(image, (0, 0), fx=scale_factor, fy=scale_factor)
    if image is None:
        raise ValueError("无法读取图像，请检查路径是否正确。")

    # 转换为灰度图
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 边缘检测（可选高斯模糊以减少噪声）
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    edges = cv2.Canny(blurred, 50, 150)

    # 使用霍夫变换检测圆形
    circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, dp=1, minDist=20,
                               param1=50, param2=30, minRadius=200, maxRadius=0)

    detected_circles = []

    if circles is not None:
        # 将检测到的圆形数据转换为整数
        circles = np.round(circles[0, :]).astype("int")

        for (x, y, r) in circles:
            # 计算直径
            diameter = r * 2

            # 存储圆形信息
            circle_info = {
                'center': (x, y),
                'radius': r,
                'diameter': diameter
            }
            detected_circles.append(circle_info)

            # 在图像上绘制圆形
            cv2.circle(image, (x, y), r, (0, 255, 0), 2)  # 绘制圆形轮廓
            cv2.circle(image, (x, y), 2, (0, 0, 255), 3)  # 绘制圆心

            # 在图像上标注直径
            cv2.putText(image, f"D={diameter}", (x - 50, y - r - 10),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 0, 0), 2)

    # 保存结果图像
    cv2.imwrite(output_path, image)

    return detected_circles


# 示例用法
if __name__ == "__main__":
    input_image_path = r"D:\data\250407lianlun\trainV8Seg_lianlun\add_imgs\cam1_MV-CH250-90GM (DA4906765)_jpg\Image_20250417152603196.jpg"  # 替换为你的输入图像路径
    output_image_path = r"D:\data\250407lianlun\other\temp\output_image.png"  # 替换为你的输出图像路径
    try:
        circles = detect_and_save_circles(input_image_path, output_image_path)
        for idx, circle in enumerate(circles):
            print(f"Circle {idx + 1}: Center {circle['center']}, "
                  f"Radius {circle['radius']}, Diameter {circle['diameter']}")
    except ValueError as e:
        print(e)